
import Foundation
import SwiftUI
import Combine
// 利用协议进行了依赖对象的抽象化提取，只要满足协议的对象都能作为依赖对象注入
protocol ProfileContentProviderProtocol: ObservableObject {
  var privacyLevel: PrivacyLevel { get }
  var canSendMessage: Bool { get }
  var canStartVideoChat: Bool { get }
  var photosView: AnyView { get }
  var feedView: AnyView { get }
  var friendsView: AnyView { get }
}
// 遵守协议的依赖对象
final class ProfileContentProvider<Store>: ProfileContentProviderProtocol where Store: PreferencesStoreProtocol{
  let privacyLevel: PrivacyLevel
  private let user: User
  private var store: Store
  private var cancellables: Set<AnyCancellable> = []
  // 依赖对象内部也采用了构造方法的注入
  init(privacyLevel: PrivacyLevel = DIContainer.shared.resolve(type: PrivacyLevel.self)!, user: User = DIContainer.shared.resolve(type: User.self)!,
       store: Store = DIContainer.shared.resolve(type: Store.self)!) {
    self.privacyLevel = privacyLevel
    self.user = user
    self.store = store
    
    store.objectWillChange.sink{_ in
      self.objectWillChange.send()
    }
    .store(in: &cancellables)
  }

  var canSendMessage: Bool {
    privacyLevel >= store.messagePreference
  }

  var canStartVideoChat: Bool {
    privacyLevel >= store.videoCallsPreference
  }

  var photosView: AnyView {
    privacyLevel >= store.photosPreference ?
      AnyView(PhotosView(photos: user.photos)) :
      AnyView(EmptyView())
  }

  var feedView: AnyView {
    privacyLevel >= store.feedPreference ?
      AnyView(HistoryFeedView(posts: user.historyFeed)) :
      AnyView(RestrictedAccessView())
  }

  var friendsView: AnyView {
    privacyLevel >= store.friendsListPreference ?
      AnyView(UsersView(title: "Friends", users: user.friends)) :
      AnyView(EmptyView())
  }
}
